package model.datastructure;

public class BlockSurface2D extends AbstractSurface2D {

	private BlockType2D mBlockType;
	private int rotation;
	private int[] topSurface;
	private int[] bottomSurface;

	/**
	 * Creates a new blocksurface from the given block, with the given dimension and rotation
	 * @param block the block of which we want the surface
	 * @param dimension the size of the desired surface
	 * @param rotation the rotation of the block from which we want the surface
	 */
	public BlockSurface2D(BlockType2D blockType, Dimension1D dimension, int rotation) {
		super(dimension);
		mBlockType = blockType;
		this.rotation = rotation;
	}

	/**
	 * Gets the surface of the block, when seen from the top.
	 * @return
	 */
	public int[] getTopSurface() {
		if (topSurface == null) {
			topSurface = calculateTopSurface();
		}
		return topSurface;
	}

	/**
	 * Gets the surface of the block, when seen from the bottom.
	 * @return
	 */
	public int[] getBottomSurface() {
		if (bottomSurface == null) {
			bottomSurface = calculateBottomSurface();
		}
		return bottomSurface;
	}
	
	/**
	 * Returns the surface, looking from the top of the field.
	 * Each position in the array denotes the number of empty y positions for that x position, looking from the top.
	 * @return surface
	 */
	private int[] calculateTopSurface() {
		//BlockType2D blockType = (BlockType2D) mBlock.getBlockType();
		/* So we have something to fill in */
		int[] surface = new int[ mBlockType.getDimension(rotation).getWidth() ];
		
		/* Loop through it left to right */
		boolean found;
		for( int indexX = 0; indexX < mBlockType.getDimension(rotation).getWidth(); indexX++ ) {
			
			/* Loop through it top to bottom */
			int indexY = mBlockType.getDimension(rotation).getHeight()-1;
			found = false;
			while (!found && indexY >= 0 ) {
				
				/* There is a ( piece of ) block here! Better make a note of it */				
				if( mBlockType.getEmptyChar() != mBlockType.getCharAt(indexX, indexY, rotation)) {

					/* Remember the current yPosition */
					surface[ indexX ] = indexY + 1;
					found = true;
				} else {
					indexY--;
				}
			}
		}
		
		/* There ya go */
		return surface;
	}
	
	/**
	 * Returns the surface, looking from the bottom of the field.
	 * Each position in the array denotes the number of empty y positions for that x position, looking from the bottom.
	 * @return surface
	 */
	public int[] calculateBottomSurface() {
		
		int[] surface = new int[ mBlockType.getDimension(rotation).getWidth() ];
		
		for( int indexX = 0; indexX < mBlockType.getDimension(rotation).getWidth(); indexX++ ) {
			
			/* Loop through it bottom to top */
			for( int indexY = 0; indexY < mBlockType.getDimension(rotation).getHeight(); indexY++ ) {
				
				/* There is a ( piece of ) block here! Better make a note of it */
				if( mBlockType.getCharAt(indexX, indexY, rotation) != mBlockType.getEmptyChar() ) {

					/* Remember the current height */
					surface[ indexX ] = indexY;
					break;
				}
			}
		}		
		return surface;
	}
	
	public int getLowest() {
		getTopSurface();
		int lowestY = Integer.MAX_VALUE;
		for (int i = 0; i < getTopSurface().length; i++){
			if (getTopSurface()[i] < lowestY) {
				lowestY = getTopSurface()[i];
			}
		}
		return lowestY;
	}

	public int getHighest() {
		int highestY = Integer.MIN_VALUE;
		for (int i = 0; i < getTopSurface().length; i++){
			if (getTopSurface()[i] > highestY) {
				highestY = getTopSurface()[i];
			}
		}
		return highestY;
	}
}